package com.t.bricks.bussiness.component.userphoneinfo;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.t.bricks.bussiness.service.userphoneinfo.UserPhoneInfoService;
import com.t.bricks.model.Log;
import com.t.bricks.model.MsgEmity;
import com.t.bricks.utils.spring.ModuleUtil;

/**
 * 用切面方式监听业务模块,然后执行'用户手机信息'相关操作
 * 注意:如非必要,请勿使用
 */
@Aspect
@Component
public class UserPhoneInfoServiceAspect {
	
	@Autowired
	private UserPhoneInfoService userPhoneInfoService;
	
	/**
	 * 定义切入点，切入点为'返回类型 被切入的实现类.切入的函数(函数参数类型)'
	 * 1、execution(public * *(..)) 任意的公共方法
	 * 2、execution(* set*(..)) 以set开头的所有的方法
	 * 3、execution(* com.lingyejun.annotation.LoggerApply.*(..))com.lingyejun.annotation.LoggerApply这个类里的所有的方法
	 * 4、execution(* com.lingyejun.annotation.*.*(..))com.lingyejun.annotation包下的所有的类的所有的方法
	 * 5、execution(* com.lingyejun.annotation..*.*(..))com.lingyejun.annotation包及子包下所有的类的所有的方法
	 * 6、execution(* com.lingyejun.annotation..*.*(String,?,Long)) com.lingyejun.annotation包及子包下所有的类的有三个参数，第一个参数为String类型，第二个参数为任意类型，第三个参数为Long类型的方法
	 * 7、execution(@annotation(com.lingyejun.annotation.Lingyejun))
	 */
	@Pointcut(value = "execution(com.t.bricks.model.MsgEmity com.t.bricks.bussiness.service.xx.impl.xxService*.add(Object,Object,String,Integer,int))")
	public void doMethod() {
	}
	
	/**
	 * 后置/返回值增强
	 * @param joinPoint
	 * @param result 被切点方法执行后的返回值
	 */
	@AfterReturning(returning="result", pointcut="doMethod()")
	public void afterReturning(JoinPoint joinPoint, Object result) {
		if (!check(joinPoint, result)) {
			return;
		}
		
		Runnable runnable = new Runnable() {
			Object[] methodArgs = joinPoint.getArgs();
	
			@Override
			public void run() {
				userPhoneInfoService.addByAop(methodArgs[0], methodArgs[1]);//注意:methodArgs为被切面的参数数组
			}
		};
		
		ModuleUtil.runThread(runnable, "BricksCommonBusiness");
	}
	
	/**
	 * 检查切面函数执行情况,判断执行结果是否符合业务要求
	 * @param joinPoint
	 * @param result 被切点方法执行后的返回值
	 * @return boolean
	 */
	private boolean check(JoinPoint joinPoint, Object result) {
		if (!(result instanceof MsgEmity)) {//不是返回MsgEmity,则说明不是要进行的切面
			MethodSignature signature = (MethodSignature) joinPoint.getSignature();
			String methodName = signature.getMethod().getName();
			Log.error("方法'", methodName, "'返回数据不是预想中的MsgEmity类,请检查代码是否被修改");
			return false;
		}

		return ((MsgEmity)result).isSuccess();
	}

}
